#ifndef IM_H
#define IM_H

#include <map>
#include <string>
#include <vector>

namespace im {
namespace citylife {
namespace proto {

enum ProtoIMConversationType {
  conv_type_none = 0,
  conv_type_person = 1,
  conv_type_group = 2,
  conv_type_system = 3,
};

enum ProtoIMMessageType {
  msg_type_none = 0,
  msg_type_text = 1,
  msg_type_image = 2,
  msg_type_file = 3,
  msg_type_voice = 4,
  msg_type_video = 5,
  msg_type_location = 6,
  msg_type_custom = 99,
};

enum ProtoImageType {
  image_type_none = 0,
  image_type_org = 1,
  image_type_thumb = 2,
  image_type_large = 4,
};

enum ProtoImageCompressLevel {
  image_compress_org = 0,
  image_compress_high = 1,
  image_compress_low = 2,
};

enum ProtoImageFormat {
  image_format_none = 0,
  image_format_jpg = 1,
  image_format_gif = 2,
  image_format_png = 3,
  image_format_bmp = 4,
  image_format_unknow = 0xff,
};

struct ProtoIMDeviceInfo {
  std::string osNameVersion; //系统版本
  std::string network;       //当前网络
  std::string networkSp;     //当前网络提供商
};

struct ProtoIMBaseInfo {
  std::string platform;         //消息类型
  std::string sdkVersion;       //消息目标方(可能是群ID)
  ProtoIMDeviceInfo deviceInfo; //接收者列表（可选）
  std::string
      vendor; //(only android platform)huawei, xiaomi, oppo, vivo, meizu, etc.
};

struct ProtoIMConnectParam {
  std::string token;       // Token
  std::string deviceId;    //设备id
  std::string packageName; //应用包名
  ProtoIMBaseInfo info;    //基本信息
};

struct ProtoIMConfigInfo {
  std::string rootDir;     // sdk相关缓存文件根目录
  std::string databaseDir; //数据路目录（已作废）
  std::string logDir;      //日志目录（已作废）
  std::int32_t
      backgroundMode; //背景运行模式 0.无障碍运行（pc端） 1.移动模式（默认）
  std::string naviDomain; // navi域名
  bool enableHttp2;       //是否启用http2.0，默认http1.1
  std::int32_t logLevel;  //日志等级
};

enum ProtoIMMessageStatus {
  msg_status_init;       //< 消息初始化状态 例如：草稿
  msg_status_sending;    //< 消息发送中
  msg_status_success;    ///< 消息发送成功
  msg_status_send_fail;  ///< 消息发送失败
  msg_status_had_del;    ///< 消息已经删除
  msg_status_had_revoke; ///< 消息已经撤消
};

struct ProtoIMDownloadFileInfo {
  std::string msgId;
  std::string senderId;
  std::string fileId;
  std::string localPath;
  std::string url;
  std::string fileType;
  std::int64_t timestamp;
};

struct ProtoIMOfflinePushInfo {
  std::string pushcontent;
  std::string pushdata;
  std::string pushtitle;
  std::string pushsubtitle;
  std::string pushsound;
};

struct ProtoIMMessageLocal {
  std::int64_t customInt;
  std::string customString;
};

struct ProtoIMMessageText {
  std::string content;
};

struct ProtoIMImage {
  std::string image_uuid;
  ProtoImageType image_type;
  std::int32_t image_size;
  std::int32_t image_heigh;
  std::int32_t image_width;
  std::string image_url;
};

struct ProtoIMMessageImage {
  std::string image_uuid;
  std::string local_path;
  ProtoImageCompressLevel compress_level;
  ProtoImageFormat format;
  std::vector<ProtoIMImage> images;
};

struct ProtoIMMessageVoice {
  std::string voice_uuid;
  std::string local_path;
  std::int32_t voice_length;
  std::string server_url;
};

struct ProtoIMMessageLocation {
  std::string longitude;
  std::string latitude;
  std::string description;
};

struct ProtoIMMessageCustom {
  std::string rawContent;
};

struct ProtoIMMessage {
  std::string msg_uuid;
  std::string sender; ///< 发送消息时确定不再改变, 是创建消息时的当前登陆用户id,
                      ///< 同时可以确定是否是发送消息
  std::string receiver; ///< 发送和接收需要改变, 如果是群消息则是群id,
                        ///< 如果是个人（发送消息是聊天对象用户（可以是登陆用户自己）,
                        ///< 接收消息是当前登陆用户）
  std::int64_t timestamp;
  ProtoIMConversationType conv_type; ///< 会话类型 1.个人 2.群组 3.系统
  ProtoIMMessageStatus msg_status;
  ProtoIMMessageType msg_type;
  bool is_send;
  bool is_online;
  ProtoIMMessageLocal local;
  std::string conv_id; ///< 发送和接收需要改变, 如果是群消息则是群id,
                       ///< 如果是个人（发送消息和接收消息都是聊天对象用户）
  std::string extra;
  union content {
    ProtoIMMessageText text;
    ProtoIMMessageImage image;
    ProtoIMMessageVoice voice;
    ProtoIMMessageLocation location;
    ProtoIMMessageCustom custom;
  };
};

struct ProtoIMMessages {
  std::vector<ProtoIMMessage> msgs;
};

struct ProtoIMConversation {
  std::string conv_id;
  ProtoIMConversationType conv_type;
  std::int64_t timestamp;
  std::string snapshot;
  std::string last_msg_uuid;
  std::string last_readed_msg_uuid;
  std::int64_t last_readed_msg_timestamp;
  std::int32_t unread_count;
  ProtoIMMessage last_msg;
};

struct ProtoIMSendMessageParams {
  ProtoIMMessageType type;
  std::map<std::string, std::string> params;
};

struct ProtoIMConversations {
  std::vector<ProtoIMConversation> convs;
};

struct ProtoIMReturnResult {
  std::map<std::string, std::string> result;
};

struct ProtoIMGetUnreadCount {
  std::int32_t count;
};

struct ProtoIMGetMessageCustomInt {
  std::int64_t value;
};

struct ProtoIMGetMessageCustomData {
  std::string value;
};

struct ProtoIMGetErrorDescription {
  std::string description;
};

} // namespace proto
} // namespace citylife
}; // namespace im

#endif // IM_H